﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Xml;

namespace Utility.ExtensionFunc
{
    public static class ExtensionFunc
    {
        public static List<T> ConvertToEntity<T>(this XmlNode doc, string nodeName) where T : class,new()
        {
            List<T> entityList = new List<T>();
            if (null == doc)
            {
                return entityList;
            }
            string pattern = string.Format(@"<{0}[^>]*?(?=/>|>)(/>|>(?<!/>)(\S|\s)*?</{0}>)", nodeName); //以指定节点作为分割 匹配节点里的内容 
            Regex reg = new Regex(pattern);
            MatchCollection matches = reg.Matches(doc.InnerXml);//通过父节点 把XML 才分成对应多个实体类的 子内容
            foreach (Match match in matches)//遍历每个子内容 （一个子内容对应一个实体类）
            {
                T _entity = new T();
                //获取实体类的所有属性（如果xml节点名称和实体类属性名称不对应 可以用Dictionary 来维护对应关系 然后这里变量Dictionary ）
                foreach (PropertyInfo propertyInfo in typeof(T).GetProperties())
                {
                    string pat = string.Format(@"(?<=<{0}>).*?(?=</{0}>)", propertyInfo.Name);//根据属性名称去 xml的子内容中找对应的节点
                    string value = Regex.Match(match.Value, pat).Value;//获取节点值
                    if (value != null)
                    {
                        switch (propertyInfo.PropertyType.Name)
                        {
                            case "Int32":
                                int i;
                                int.TryParse(value, out i);
                                propertyInfo.SetValue(_entity, i, null);//将节点值添加到 实体类中对应的属性
                                break;
                            case "String":
                                propertyInfo.SetValue(_entity, value, null);//将节点值添加到 实体类中对应的属性
                                break;
                            case "Decimal":
                                decimal d;
                                decimal.TryParse(value, out d);
                                propertyInfo.SetValue(_entity, d, null);//将节点值添加到 实体类中对应的属性
                                break;
                            case "DateTime":
                                DateTime date;
                                DateTime.TryParse(value, out date);
                                propertyInfo.SetValue(_entity, date, null);//将节点值添加到 实体类中对应的属性
                                break;
                            default:

                                break;
                        }

                    }
                }
                entityList.Add(_entity);//获取到的实体类放入 列表
            }
            return entityList;

        }

        public static XmlElement ConvertToXML<T>(this T entity, XmlDocument doc, string nodeName)
        {
            if (string.IsNullOrEmpty(nodeName) || null == entity || null == doc)
            {
                return null;
            }

            XmlElement newNode = doc.CreateElement(nodeName);
            foreach (PropertyInfo propertyInfo in typeof(T).GetProperties())
            {
                XmlElement node = doc.CreateElement(propertyInfo.Name);
                switch (propertyInfo.PropertyType.Name)
                {
                    case "Int32":
                    case "String":
                    case "Decimal":
                        node.InnerText = propertyInfo.GetValue(entity, null).ToString();
                        break;
                    case "DateTime":
                        node.InnerText = ((DateTime)propertyInfo.GetValue(entity, null)).ToString("yyyy/MM/dd HH:mm:ss");
                        break;
                    default:

                        break;
                }

                newNode.AppendChild(node);
            }

            return newNode;
        }
    }
}
